package cn.s1995.sloth.bms.controller;

import cn.hutool.core.map.MapUtil;
import cn.s1995.sloth.bizs.service.common.MailService;
import cn.s1995.sloth.common.core.constant.enums.hint.Hint;
import cn.s1995.sloth.bizs.entity.Demo;
import cn.s1995.sloth.bizs.service.DemoService;
import cn.s1995.sloth.bizs.service.TestService;
import cn.s1995.sloth.bizs.service.common.CommonService;
import cn.s1995.sloth.bizs.service.impl.TestServiceImpl;
import cn.s1995.sloth.bizs.util.CacheManagerUtil;
import cn.s1995.sloth.common.core.util.R;
import cn.s1995.sloth.common.idempotent.annotation.Idempotent;
import cn.s1995.sloth.common.security.annotation.Inner;
import cn.s1995.sloth.common.sequence.sequence.Sequence;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * TestController
 *
 * @Author Lex
 * @Description
 * @Date 2023/11/10 17:34
 */
@Slf4j
@Inner(value = false)
@RestController
@RequestMapping("/test")
@ApiSort(1)
@ApiSupport(order = 1, author = "Lex")
@Tag(description = "Test", name = "BMS-测试接口")
@AllArgsConstructor
public class TestController {

    private final DemoService demoService;
    private final TestService testService;
    private final CommonService commonService;
    private final Sequence orderSequence;
    private final Sequence refundSequence;
    private final CacheManagerUtil cacheManagerUtil;
    private final MailService mailService;

    @ApiOperationSupport(order = 1)
    @Operation(summary = "测试幂等", description = "")
    @Idempotent(key = "#key", expireTime = 5, info = "请勿重复查询")
    @GetMapping("/idempotent")
    public R<String> idempotent(String key) {
        return R.ok(key);
    }

    @ApiOperationSupport(order = 2)
    @Operation(summary = "测试幂等2", description = "")
    @Idempotent(expireTime = 5)
    @GetMapping("/idempotent2")
    public R<String> idempotent2(String key) {
        return R.ok(key);
    }

    @ApiOperationSupport(order = 3)
    @Operation(summary = "测试获取图片前缀转换", description = "")
    @GetMapping("/getFilePrefixJoinHandler")
    public R<List<Demo>> getFilePrefixJoinHandler() {
        return R.ok(demoService.list());
    }

    @ApiOperationSupport(order = 4)
    @Operation(summary = "测试分布式锁", description = "")
    @GetMapping("/redisson")
    public R redisson(String goodId, int num) {
        return testService.deductCommodityInventory(goodId, num);
    }

    @ApiOperationSupport(order = 4)
    @Operation(summary = "测试锁-创建订单", description = "")
    @PostMapping("/redisson/createOrder")
    public R createOrder(@RequestBody TestServiceImpl.PayParamREQ req) {
        return testService.createOrder(req);
    }

    @ApiOperationSupport(order = 5)
    @Operation(summary = "测试Hint国际化", description = "")
    @GetMapping("/i18n/hint")
    public R i18nHint() {
        return R.ok(Hint.NON_VERIFY_FREQUENTLY_SEND, null, "60");
    }

    @ApiOperationSupport(order = 6)
    @Operation(summary = "测试发送邮件", description = "")
    @GetMapping("/email")
    public R email(String email, String subject, String content) {
        mailService.sendSimpleText(email, subject, content);
        return R.ok();
    }

    @ApiOperationSupport(order = 7)
    @Operation(summary = "测试缓存序列化", description = "")
    @GetMapping("/cache/serialize")
    public R cache(@RequestParam Long id) {
        return R.ok(demoService.getDemo(id));
    }

    @ApiOperationSupport(order = 8)
    @Operation(summary = "测试JoinUrl", description = "")
    @GetMapping("/join-url/serialize")
    public R JoinUrl() {
        return R.ok(demoService.list());
    }

    @ApiOperationSupport(order = 8)
    @Operation(summary = "测试发号器", description = "")
    @GetMapping("/sequence")
    public R sequence() {
        Map<String, String> build = MapUtil.builder(new HashMap<String, String>())
                .put("orderSequence", orderSequence.nextNo())
                .put("refundSequence", refundSequence.nextNo())
                .build();
        return R.ok(build);
    }

    @ApiOperationSupport(order = 9)
    @Operation(summary = "测试事务回滚", description = "")
    @GetMapping("/transactional")
    public R transactional(Boolean isException, Boolean isSelf) {
        demoService.transactional(isException, isSelf);
        return R.ok();
    }

    @ApiOperationSupport(order = 10)
    @Operation(summary = "获取缓存", description = "")
    @GetMapping("/cache")
    public R transactional(String name, String key) {
        return R.ok(cacheManagerUtil.getCache(name, key));
    }
}
